import axios, { type InternalAxiosRequestConfig } from 'axios';
import { ElMessage, ElLoading } from 'element-plus';
import { ref } from 'vue';

export const instance = axios.create({
  baseURL: '/api',
  timeout: 5000,
  headers: {
    'Content-Type': 'application/json',
  },
});

let loadCount = 0;

let loadingInstance = ref<any>(null);

const addLoading = () => {
  loadCount += 1;
  if (loadCount === 1) {
    loadingInstance.value = ElLoading.service({
      fullscreen: false,
      text: '正在请求数据中……',
      background: 'rgba(0, 0, 0, 0)',
    });
  }
};

const cancelLoading = () => {
  loadCount -= 1;
  if (loadCount === 0) {
    loadingInstance.value.close();
  }
};

instance.interceptors.request.use((config: InternalAxiosRequestConfig & { loading?: boolean }) => {
  const token = sessionStorage.getItem('token');
  if (token) {
    config.headers['token'] = token;
  }
  if (config.loading !== false) {
    addLoading();
  }
  return config;
}, (error) => {
  Promise.reject(error);
});

instance.interceptors.response.use((res) => {
  cancelLoading();
  if (res.data.code === 0) {
    return res.data;
  } else {
    ElMessage.error(res.data.msg);
    return Promise.reject(new Error(res.data.msg));
  }
}, (error) => {
  cancelLoading();
  if (error && error.response) {
    const { status } = error.response;
    switch (status) {
      case 400:
        ElMessage.error('请求错误');
        break;
      case 401:
        ElMessage.error("未授权，请重新登录");
        break;
      case 403:
        ElMessage.error("登录过期，请重新登录");
        break;
      case 404:
        ElMessage.error("请求错误，未找到相应的资源");
        break;
      case 408:
        ElMessage.error("请求超时");
        break;
      case 500:
        ElMessage.error("服务器错误");
        break;
      case 504:
        ElMessage.error("网络超时");
        break;
      default:
        ElMessage.error("请求失败");
        break;
    }
  } else {
    if (JSON.stringify(error).includes('timeout')) {
      error.code = 'TIMEOUT';
      error.message = '服务器响应超时，请刷新页面';
    }
  }
  return Promise.reject(error);
});

export default instance;
